<template>
  <div class="page-view" :class="[scrollable?'is__scroll': '']">

    <div class="page-header" v-if="$slots.header">
      <!--  头部视图固定  -->
      <!--  具名插槽 在父组件使用v-lot指令 并以参数为header形式提供其名称 则其所有内容都会被传到这个插槽下    -->
      <slot name="header"></slot>
    </div>
    <div class="page-content" v-if="$slots.default">
      <div class="page-content-inner" ref="contentInnerRef">
        <!--  内容区视图 默认插槽内容  -->
        <!--  为了让contentHeight在父级的插槽内容中可用，我们可以将contentHeight作为slot 元素的一个 attribute 绑定上去（可以为一个对象 也可以多个插槽属性）     -->
        <slot :contentHeight="contentHeight"></slot>
      </div>
    </div>
    <div class="page-footer" v-if="$slots.footer">
      <!--  底部视图固定  -->
      <slot name="footer"></slot>
    </div>
  </div>
</template>
<script>
// 防抖
import {mapState} from "vuex";
import {util} from "@/utils/util";

const useDebounce = (callback, delay = 200)=>{
  let timer;
  return ()=>{
    if(timer)window.clearTimeout(timer);
    timer = setTimeout(()=>{
      callback();
    },delay)
  }
}
export default {
  name: 'page-view',
  props:{
    // 是否使用内部滚动 当只需要表格滚动时 该值为false 默认是整个页面的滚动(当高度撑满溢出时 出现滚动条)
    // 当需要依赖于页面容器的滑动 而不是表格滑动时 此值打开(此时无需设置表格高度, 并可以将头尾视图一起放到内容区 一起滑动)
    scrollable:{
      type: Boolean,
      default: true
    },
    clearClass:{
      type: Boolean,
      default: true
    },
    // 影响布局的变量 比如表单页面的分页组件 为对象 只要是涉及到布局动态显示的变量 均可以加入到对象里面
    layoutVars:{
      type: Object,
      default: ()=>({})
    }
  },
  data(){
    return {
      // 绑定在slot上的属性 插槽属性
      contentHeight: 0,
      resizeBounceFn: useDebounce(()=>{
        // 变了
        this.calcHeight();
      })
    }
  },
  mounted() {
    // 初始触发一下
    this.calcHeight();
    // 监听窗体大小变化
    window.addEventListener('resize',this.resizeBounceFn);
  },
  // 组件被激活时
  activated() {
    console.log('activated')
    // this.calcHeight()
  },
  destroyed() {
    window.removeEventListener('resize',this.resizeBounceFn);
  },
  watch:{
    'clearClass':{
      handler(val){
        // 添加一个全局样式:清除上层元素设置的不符合要求的样式
        const classname = 'page-view__clear';
        if(val) {
          document.body.classList.add(classname)
        } else {
          document.body.classList.remove(classname)
        }
      },
      immediate: true
    },
    // 可能影响布局的变量 一旦变化 则需要重新计算高度
    outerLayoutParams:{
      handler(val) {
        // 变化即重新计算内容高度
        console.log('变量变化 页面需要计算高度')
       this.layoutUpdated();
      },
      immediate: true,
      deep: true
    }
  },
  computed:{
    ...mapState({
      needTagsView: state => state.settings.tagsView,
      fixedHeader: state => state.settings.fixedHeader,
    }),
    // 对布局产生影响的变量 布局根据这些值可能会发生变化
    outerLayoutParams(){
      return [
        this.needTagsView,
        this.fixedHeader,
        this.layoutVars
      ];
    }
  },
  methods:{
    // 计算内容区高度
    calcHeight(){
      const contentEl = this.$refs.contentInnerRef;
      console.log('contentEl:', contentEl)
      if (util.needLog()) {
        // 整个容器的高度
        const elContainerHeight = document.querySelectorAll('.el-container')[0].clientHeight;
        console.log('整个容器的高度:', elContainerHeight);

        // 导航和标签部分高度
        const elHeaderHeight = document.querySelectorAll('.el-header')[0].clientHeight;
        console.log('导航和标签部分高度:', elHeaderHeight);

        // 显示内容区的高度（表单 表格 底部分页）
        const elMainHeight = document.querySelectorAll('.el-main')[0].clientHeight;
        console.log('显示内容区的高度:', elMainHeight);

        // 页面头部高度
        const appSectionHeader = document.querySelectorAll('.app-section-header')
        if (appSectionHeader && appSectionHeader.length > 0) {
          const appSectionHeaderHeight = appSectionHeader[0].clientHeight;
          console.log('页面头部表单高度:', appSectionHeaderHeight);
        }

        // 页面底部高度
        const appSectionFooter = document.querySelectorAll('.app-section-footer')
        if (appSectionFooter && appSectionFooter.length > 0) {
          const appSectionFooterHeight = appSectionFooter[0].clientHeight;
          console.log('页面底部分页高度:', appSectionFooterHeight);
        }

        // console.log('PageHeight:',this.$el.clientHeight)
      }

      if(contentEl) {
        console.log('calcHeight', contentEl.clientHeight);
        this.contentHeight = contentEl.clientHeight;
      }
    },
    layoutUpdated(){
      // 重新计算
      this.$nextTick(()=>{
        this.calcHeight();
      })
    }
  }
}
</script>



<style scoped lang="scss">

.page-view{
  display: flex;
  height: 100%;
  flex-direction: column;
  --page-view-overflow: hidden;

  // 如果页面支持滑动 则放开溢出
  &.is__scroll{
    --page-view-overflow: auto;
  }

  .page-form{
    flex: none;
  }

  .page-content{
    flex: 1;
    overflow: hidden;
    display: flex;
    .page-content-inner{
      flex: 1;
      width: 100%;
      overflow: var(--page-view-overflow);
      // 表格区域最低高度限制200px
      min-height: 200px;
    }
  }

  .page-footer{
    flex: none;
  }
}
</style>

<style lang="scss">
body.page-view__clear{
  .app-main{
    min-height: auto;
    height: 100%;
  }
  .app-section-footer{
    height: auto;
  }
}

</style>
